<?php
include_once "User_DAO.php";
include_once "Item.php";
include_once "Report.php";

class User extends User_DAO{
	/**
	 * Return the last report.<br>
	 * That is to say a Report which has been created within the past 7 days
	 * @return Report a Report instance
	 */
	public function getLastReport(){
		$l_results=Report::getFromCustomCriteria("where User_id=:User_Id AND validated=:validated group by User_id having min(createdDate)",
			array(
				"User_Id" => $this->getId(),
				"validated" => false
			));
		if(count($l_results)!=0){
			return array_shift($l_results);
		}
		return NULL;
	}
	
	/**
	 * Extension of the base class.
	 * Returns a full name created from the First name, the Last name and thee-mail of the user.
	 * @return string
	 */
	public function getFullName(){
		return $this->getFirstName(). " " . $this->getLastName() . " (" . $this->getEmail() . ")";
	}
	
	/**
	 * Returns the actions which are opened and allocated to this user
	 * @return array an array of Item (which are actions) indexed by Id
	 */
	public function getOpenAllocatedActions(){
		$l_records=Item::getFromCustomCriteria("WHERE AllocatedUser_id=:AllocatedUser_id AND ItemType_id=:ItemType_id AND ItemStatus_id=:ItemStatus_id ORDER BY TargetDate",
		array(
			"AllocatedUser_id" =>$this->getId(),
			"ItemType_id" => Item::ACTION_TYPE,
			"ItemStatus_id" => Item::ACTION_STATUS_OPENED));
		return $l_records;
	}
	
	/**
	 * Returns the number of actions which are opened and allocated to this user
	 * @return array an array of Item (which are actions) indexed by Id
	 */
	public function getOpenAllocatedActionsCount(){
		$l_value=Item::getCustomCount("WHERE AllocatedUser_id=:AllocatedUser_id AND ItemType_id=:ItemType_id AND ItemStatus_id=:ItemStatus_id ORDER BY TargetDate",
		array(
			"AllocatedUser_id" =>$this->getId(),
			"ItemType_id" => Item::ACTION_TYPE,
			"ItemStatus_id" => Item::ACTION_STATUS_OPENED));
		return $l_value;
	}
	
	/**
	 * Returns the actions which are opened and have been created by this user
	 * @return array an array of Item (which are actions) indexed by Id
	 */
	public function getOpenCreatedActions(){
		$l_records=Item::getFromCustomCriteria("WHERE CreatingUser_id=:CreatingUser_id AND ItemType_id=:ItemType_id AND ItemStatus_id=:ItemStatus_id  ORDER BY TargetDate",
			array(
				"CreatingUser_id" =>$this->getId(),
				"ItemType_id" => Item::ACTION_TYPE,
				"ItemStatus_id" => Item::ACTION_STATUS_OPENED));
		return $l_records;
	}
	
	/**
	 * Returns the activities for which the user is responsible and that are not archived
	 * @return array an array of Activity objects
	 */
	public function getOpenActivities(){
		return Activity::getFromCustomCriteria("WHERE isArchived=:isArchived AND ResponsibleUser_Id=:ResponsibleUser_Id",
			array("isArchived" => false,
				"ResponsibleUser_Id" => $this->getId()));
	}
	
	/**
	 * Extension of the base class.
	 * Returns the full team of the specified user (recursive search)
	 */
	public function getFullTeam(){
		return User::getTeamRecursiveSearch($this->getId(), $this->getId());
	}
	
	/**
	 * Check if the specified userId is associated with a direct or indirect manager.<br>
	 * "ManagerUser_Id field identify the direct manager.<br>
	 * An "indirect" manager can be the manager of my direct manager.
	 * @param string $p_managerId the Id of a user
	 * @return boolean True if the specified managerId is the one of a direct or indirect manager of this
	 */
	public function isUserManager($p_managerId){
		$l_managers=User::getManagersRecusiveSearch($this, $this->getId());
		return array_key_exists($p_managerId,$l_managers);
	}
	
	/**
	 * Return the complete list of direct or indirect managers (that is to say a table of User indexed by Id)
	 * @param User $p_user the user which manager is searched
	 * @param string $p_initialUserId the initial user (used to prevent loops)
	 * @return array
	 */
	public static function getManagersRecusiveSearch($p_user, $p_initialUserId){
		$l_managers=array();
		$l_manager=$p_user->getManagerUser_Id_Ref();
		if(isset($l_manager) && $l_manager->getId()!=$p_initialUserId){
			$l_managers[$l_manager->getId()]=$l_manager;
			$l_managers=array_merge($l_managers,User::getManagersRecusiveSearch($l_manager,$p_initialUserId));
		}
		return $l_managers;
	}
	
	/**
	 * Return my team (full recusive search) that is to say a table of User indexed by Id
	 * @param string $p_userId The Id of the user which team is searched
	 * @param string $p_managerId The Id of the top level manager (used to prevent loops)
	 */
	private static function getTeamRecursiveSearch($p_userId, $p_managerId){
		$l_fullTeam=array();
		$l_teamMembers=User::getFromCustomCriteria("WHERE ManagerUser_Id=:ManagerUser_Id", array("ManagerUser_Id" => $p_userId));
		foreach($l_teamMembers as $l_teamMember){
			if($l_teamMember->getId()!=$p_managerId){
				$l_fullTeam[$l_teamMember->getId()]=$l_teamMember;
				$l_subTeam=User::getTeamRecursiveSearch($l_teamMember->getId(), $p_managerId);
				if(count($l_subTeam)!=0){
					$l_fullTeam=array_merge($l_fullTeam,$l_subTeam);
				}
			}
		}
		
		return $l_fullTeam;
	}
}
?>